// TODO
package instructions;

import expressions.BadExpressionException;
import expressions.Expression;
import values.Array;
import values.Value;
import base.AST;
import base.Environment;
import base.Identifier;

public class ArrayDef implements Instruction {

	private Identifier name;
	private AST[] items;
	
	/**
	 *  Creates the instruction 
	 *  identifier = [items]
	 */
	public ArrayDef(Identifier name, AST[] items) {
		this.name = name;
		this.items = items;
	}

	/**
	 * changes the value of identifier in the environment by building an array of values
	 */
	public Environment instr(Environment env) throws BadInstructionException {

		Value[] values = new Value[this.items.length];

		for (int i = 0; i < values.length; i++) {

			if (items[i] instanceof Expression)
				try {
					values[i] = ((Expression) items[i]).eval(env);
				} catch (BadExpressionException e){
					throw new BadInstructionException(e, "Bad expression in definition of array "
							+ this.name.getName());
				}
			else if (items[i] instanceof Value)
				values[i] = (Value) items[i];
			else
				throw new BadInstructionException("Values in array " +  this.name.getName() + " must be expressions or values");

		}

		Array newArray = new Array(values);

		Environment newEnv = env.clone();
		newEnv.update(this.name, newArray);

		return newEnv;
	}
}
